package com.lxf.clouduser.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lxf.clouduser.service.UserFlowAbleService;
import liquibase.pro.packaged.E;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * @author 罗兴发
 * @data 2025/7/25 14:05
 * @description：工作流-业务实现层
 */
@Service
@Slf4j
public class UserFlowAbleServiceImpl implements UserFlowAbleService {
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private ProcessEngine processEngine;
    @Override
    public String appSettled(JSONObject json, HttpServletRequest request) {
        JSONObject js = new JSONObject();

        // 获取前端传递的参数
        Integer userId = json.getInteger("user_id");
        Integer days = json.getInteger("days");
        String desc = json.getString("desc");

        // 设置流程参数,用户名等等
        HashMap<String, Object> map = new HashMap<>();
        map.put("userTask", userId);
        map.put("days", days);
        map.put("desc", desc);
        // 启动一个流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave_flow", map);
        // 生成一个任务
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        log.info("代办任务：{}",task);
        // 第一步任务流程完成后，会按照流程图自动分配给下一个流程
        taskService.complete(task.getId());

        // 封装返回消息
        String data = "提交成功\n流程Id为：" + processInstance.getId()
                + "\n任务id: " + task.getId()
                + "\n请假人为：" + userId
                + "\n请假天数为：" + days
                + "\n描述为：" + desc;

        // json封装
        js.put("code",200);
        js.put("msg","Success");
        js.put("data",data);

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String findTask(JSONObject json, HttpServletRequest request) {
        JSONObject js = new JSONObject();

        // 获取用户角色名称
        String Id = json.getString("user_id");

        // 从引擎中获取任务
        TaskService taskService = processEngine.getTaskService();
        log.info("代办任务：{}",taskService.createTaskQuery().taskAssignee(Id).list());
        Task task = taskService.createTaskQuery().taskAssignee(Id).singleResult();
        String id = task.getId();

        // 封装消息返回
        String data = Id + "的任务ID："+id;

        // json封装
        js.put("code",200);
        js.put("msg","Success");
        js.put("data",data);

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String getList(JSONObject json, HttpServletRequest request) {
        JSONObject js = new JSONObject();
        String userId = json.getString("user_id");
        Map<String,String> result = new HashMap<>();
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).orderByTaskCreateTime().desc().list();
        for (Task task : tasks) {
            result.put(task.getName(),task.getId());
        }

        // json封装
        js.put("code",200);
        js.put("msg","Success");
        js.put("data",result);

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String apply(JSONObject json, HttpServletRequest request) {
        JSONObject js = new JSONObject();

        String taskId = json.getString("task_id");

        // 获得任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("流程不存在");
        }

        // 通过审核
        HashMap<String, Object> map = new HashMap<>();
        map.put("result", "同意");
        taskService.complete(taskId, map);
        // json封装
        js.put("code",200);
        js.put("msg","Success");
        js.put("data","任务ID：" + taskId + "---批准!");

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String reject(JSONObject json, HttpServletRequest request) {
        JSONObject js = new JSONObject();

        String taskId = json.getString("task_id");
        // 获得任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("流程不存在");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("result", "驳回");
        taskService.complete(taskId, map);

        // json封装
        js.put("code",200);
        js.put("msg","Success");
        js.put("data","任务ID：" + taskId + "---驳回!");

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String getProcessDiagram(JSONObject json, HttpServletRequest request, HttpServletResponse response) {
        JSONObject js = new JSONObject();
        try {
            String taskId = json.getString("task_id");

            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(taskId).singleResult();

            // 流程走完的不显示图
            if (pi == null) {

                // json封装
                js.put("code",401);
                js.put("msg","Fails");

                return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
            }
            Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();

            // 使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
            String InstanceId = task.getProcessInstanceId();
            List<Execution> executions = runtimeService
                    .createExecutionQuery()
                    .processInstanceId(InstanceId)
                    .list();

            // 得到正在执行的flowable的Id
            List<String> flowableIds = new ArrayList<>();
            List<String> flows = new ArrayList<>();
            for (Execution exe : executions) {
                List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
                flowableIds.addAll(ids);
            }

            // 获取流程图
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
            ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
            ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
            InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", flowableIds, Collections.emptyList(), engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), null, 1.0, false);
            OutputStream out = null;
            byte[] buf = new byte[10240];
            int legth = 0;
            try {
                // 设置响应类型为图片
                response.setContentType("image/png");
                out = response.getOutputStream();
                while ((legth = in.read(buf)) != -1) {
                    out.write(buf, 0, legth);
                }
            } catch (IOException e) {
                System.out.println("生成流程图失败");
                throw new RuntimeException(e);
            } finally {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        // json封装
        js.put("code",200);
        js.put("msg","Success");

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }
}
